﻿using System;
using System.IO;
using CoreTypes;
using System.Text;
using System.Linq;
using System.Custom;
using System.Xml.Linq;
using HtmlViewControl;
using System.Collections;
using System.Custom.Window;
using System.Windows.Forms;
using System.ComponentModel;
using MainModule.Properties;
using System.Collections.Generic;

namespace MainModule
{
   public partial class EventViewer : Window
   {
      #region Window Data

      int FEventCount;
      HtmlView FHtmlView;
      InternetCommunicator FCommunicator = InternetCommunicator.Self;

      #endregion

      public EventViewer()
      {
         InitializeComponent();

         ColorTheme = InternetCommunicator.Self.ColorTheme;
         RenderMode = InternetCommunicator.Self.RenderMode;

         FCommunicator.LogEvent += communicator_LogEvent;
         FCommunicator.PropertyChanged += communicator_PropertyChanged;

         FHtmlView = new HtmlView();
         tableLayoutPanel.Controls.Add(FHtmlView);

         ShowEventLog();
      }
      protected override void Dispose(bool disposing)
      {
         FCommunicator.LogEvent -= communicator_LogEvent;
         FCommunicator.PropertyChanged -= communicator_PropertyChanged;
         if (disposing && (components != null))
         {
            components.Dispose();
         }
         base.Dispose(disposing);
      }

      public override ColorTheme ColorTheme
      {
         get
         {
            return base.ColorTheme;
         }
         set
         {
            base.ColorTheme = value;
            Refresh();
         }
      }
      public override ToolStripRenderMode RenderMode
      {
         get
         {
            return base.RenderMode;
         }
         set
         {
            toolStrip.RenderMode = value;
            statusBar.RenderMode = value;
            //statusBar.Refresh();
         }
      }

      private void ShowEventLog()
      {
         string html = LoadEventLog(false);

         FHtmlView.LoadHtml(html, "");

         FHtmlView.HtmlBody.ScrollToEnd(false);

         statusBarLabel.Text = Resources.S_Entries_in_log.Replace("<count>", FEventCount.ToString());

         FCommunicator.OptimizeMemorySize();
      }
      private string LoadEventLog(bool full)
      {
         IEnumerable<XElement> xLog = XElement.Parse(FCommunicator.EventLog.LoadSystemLog()).Elements();

         FEventCount = xLog.Count();

         if (!full) xLog = xLog.Skip(FEventCount < 100 ? 0 : FEventCount - 100);

         StringBuilder html = new StringBuilder(2048 + xLog.Count() * 80 /* avg length of data */);

         html.AppendFormat(Resources.LogBlank, Resources.CommonLogStyle + Resources.EventViewerStyle, full ? "" : Resources.T_HtmlMenu, "");

         foreach (XElement item in xLog)
         {
            SystemEvent se = new SystemEvent(item);
            html.AppendFormat(Resources.T_SystemEvent, se.Title.ToLower(), se.Title, se.DateTime, se.Message, se.StackTrace);
         }
         return html.ToString();
      }

      private void buttonClear_Click(object sender, EventArgs e)
      {
         if (MessageBox.Show(Resources.S_Do_you_really_want_to_clear_log_file, Text,
             MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
         {
            FCommunicator.EventLog.ClearSystemLog();
            DelayedAction.Do(() => ShowEventLog(), 1000);
         }
      }
      private void buttonSaveHtml_Click(object sender, EventArgs e)
      {
         File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\" + InternetCommunicator._AppName + "SystemLog.html", LoadEventLog(true), Encoding.Unicode);
         FCommunicator.ShowMessage(Resources.S_Saved_to_the_desktop, true);
      }
      private void statusBar_Paint(object sender, PaintEventArgs e)
      {
         InternetCommunicator.Self.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.StatusStrip);
         InternetCommunicator.Self.DrawStatusBar(ColorTheme, sender as StatusStrip, e.Graphics);
      }
      private void toolStrip_Paint(object sender, PaintEventArgs e)
      {
         InternetCommunicator.Self.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.ToolStrip);
      }
      private void textBoxFilter_KeyUp(object sender, KeyEventArgs e)
      {
         if (e.KeyCode == Keys.Enter)
         {
            if (e.Shift) FHtmlView.FindPrev(); else FHtmlView.FindNext();
         }
      }
      private void textBoxFilter_TextChanged(object sender, EventArgs e)
      {
         if (textBoxFilter.Text.Length != 1)
         {
            DelayedAction.Do(sender, () =>
            {
               FHtmlView.FindText(textBoxFilter.Text, "span.text", true);
            },
            600, true);
         }
      }
      private void communicator_LogEvent(object sender, DefaultEventArgs e)
      {
         if (e.EventData is SystemEvent)
         {
            SystemEvent se = e.EventData as SystemEvent;
            FHtmlView["log"].HtmlElement.AddHtml(string.Format(Resources.T_SystemEvent, se.Title.ToLower(), se.Title, se.DateTime, se.Message, se.StackTrace), true);

            statusBarLabel.Text = Resources.S_Entries_in_log.Replace("<count>", (++FEventCount).ToString());
         }
      }
      private void communicator_PropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "ColorTheme") ColorTheme = FCommunicator.ColorTheme;
         else if (e.PropertyName == "RenderMode") RenderMode = FCommunicator.RenderMode;
      }
   }
}
